﻿//负责监听 VisionMaster 发来的 OK/NG 结果（TCP 服务器，监听 9528 端口）。

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms; // 需要引用 System.Windows.Forms 来使用 Control.BeginInvoke

namespace ShangWeiDemo1
{
    /// <summary>
    /// 监听 VisionMaster 发送的 OK/NG 结果 (作为 TCP Server)
    /// </summary>
    public class TcpServerListener
    {
        private TcpListener _resultListener;
        private CancellationTokenSource _cts;
        private readonly int _listenPort;
        private readonly Action<string> _logAction;
        // 使用 Action 委托将结果回调给主窗体的 ProcessFinalResult(string, string) 方法
        private readonly Action<string, string> _resultCallback;
        // 使用 Control 类型来安全地调用 BeginInvoke
        private readonly Control _uiControl;

        // 关键修复：构造函数签名已修正，接收 Control uiControl
        public TcpServerListener(int listenPort, Action<string> logAction, Action<string, string> resultCallback, Control uiControl)
        {
            _listenPort = listenPort;
            _logAction = logAction;
            _resultCallback = resultCallback;
            // 关键修复：使用传入的 uiControl
            _uiControl = uiControl;
        }

        private void WriteToLogFile(string msg) => _logAction?.Invoke(msg);

        /// <summary>
        /// 启动 VisionMaster 结果监听服务
        /// </summary>
        public void StartListening()
        {
            _cts = new CancellationTokenSource();
            // 使用 Task.Run 启动监听循环，避免阻塞主线程
            Task.Run(() => ListenLoopAsync(_cts.Token));
        }

        /// <summary>
        /// 停止监听服务
        /// </summary>
        public void StopListening()
        {
            _cts?.Cancel();
            try { _resultListener?.Stop(); } catch { }
            _resultListener = null;
        }

        /// <summary>
        /// 异步监听循环
        /// </summary>
        private async Task ListenLoopAsync(CancellationToken token)
        {
            try
            {
                // 监听所有网络接口的 IP 地址
                _resultListener = new TcpListener(IPAddress.Any, _listenPort);
                _resultListener.Start();
                WriteToLogFile($"VisionMaster 结果监听服务已启动，端口: {_listenPort}");

                while (!token.IsCancellationRequested)
                {
                    // 使用 token 优雅地处理关闭时的阻塞
                    Task<TcpClient> acceptTask = _resultListener.AcceptTcpClientAsync();

                    // 等待接受连接或取消信号
                    await Task.WhenAny(acceptTask, Task.Delay(Timeout.Infinite, token));

                    if (token.IsCancellationRequested)
                    {
                        break; // 收到取消信号，退出循环
                    }

                    // 接受客户端连接
                    TcpClient client = await acceptTask;
                    // 异步处理该客户端数据，不阻塞主循环
                    // 使用 _ = 忽略返回的 Task，实现 fire-and-forget
                    _ = HandleVisionMasterResultClient(client, token);
                }
            }
            catch (ObjectDisposedException) when (token.IsCancellationRequested)
            {
                // 正常关闭，忽略
            }
            catch (Exception ex)
            {
                if (!token.IsCancellationRequested)
                {
                    WriteToLogFile($"VisionMaster 结果监听失败: {ex.Message}");
                }
            }
        }

        /// <summary>
        /// 处理 VisionMaster 发送的 OK/NG 结果数据
        /// </summary>
        private async Task HandleVisionMasterResultClient(TcpClient client, CancellationToken token)
        {
            WriteToLogFile($"VisionMaster 连接接入: {client.Client.RemoteEndPoint}");

            using (client) // 确保客户端连接最终会被关闭
            using (NetworkStream stream = client.GetStream())
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                try
                {
                    // 长连接循环：持续读取数据
                    while (!token.IsCancellationRequested && client.Connected)
                    {
                        // 异步读取一行数据
                        Task<string> readTask = reader.ReadLineAsync();

                        // 等待读取或取消
                        await Task.WhenAny(readTask, Task.Delay(Timeout.Infinite, token));

                        if (token.IsCancellationRequested) break; // 取消信号

                        string result = await readTask;

                        // 检查客户端是否主动断开连接
                        if (string.IsNullOrEmpty(result))
                        {
                            WriteToLogFile("VisionMaster 客户端主动关闭连接。");
                            break;
                        }

                        // 处理接收到的数据
                        string trimmedResult = result.Trim();
                        WriteToLogFile($"接收到 VisionMaster 原始结果: [{trimmedResult}]");

                        string[] parts = trimmedResult.Split(',');
                        if (parts.Length == 2)
                        {
                            string barcode = parts[0].Trim();
                            string finalResult = parts[1].Trim().ToUpper();

                            // 核心：调用 ProcessFinalResult 更新 UI (必须通过 BeginInvoke)
                            // 检查 UI 控件是否已释放，以避免 ObjectDisposedException
                            if (_uiControl != null && !_uiControl.IsDisposed)
                            {
                                _uiControl.BeginInvoke(_resultCallback, barcode, finalResult);
                            }
                        }
                        else
                        {
                            WriteToLogFile($"VisionMaster 结果格式错误: [{trimmedResult}]");
                        }
                    }
                }
                catch (IOException ioEx)
                {
                    WriteToLogFile($"VisionMaster 客户端 I/O 错误 (连接断开): {ioEx.Message}");
                }
                catch (Exception ex)
                {
                    WriteToLogFile($"处理 VisionMaster 结果时发生异常: {ex.Message}");
                }
            }
            WriteToLogFile($"VisionMaster 连接断开。");
        }
    }
}